<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Cookie | yanyan</title>
    <meta name="description" content="Yan&#39;s blog">
    <meta name="generator" content="VuePress 1.4.0">
    <script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.slim.min.js"></script>
  <script src="https://cdn.bootcss.com/fancybox/3.5.7/jquery.fancybox.min.js"></script>
  <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/fancybox/3.5.7/jquery.fancybox.min.css">
  <link rel="shortcut icon" type="image/x-icon" href="./favicon.ico">
    
    <link rel="preload" href="/assets/css/0.styles.e1b3f17d.css" as="style"><link rel="preload" href="/assets/js/app.e358a08d.js" as="script"><link rel="preload" href="/assets/js/2.88fa18d1.js" as="script"><link rel="preload" href="/assets/js/32.eb64932c.js" as="script"><link rel="prefetch" href="/assets/js/10.23baf844.js"><link rel="prefetch" href="/assets/js/11.45c148ba.js"><link rel="prefetch" href="/assets/js/12.e5930132.js"><link rel="prefetch" href="/assets/js/13.0547cd14.js"><link rel="prefetch" href="/assets/js/14.3e67795b.js"><link rel="prefetch" href="/assets/js/15.51129890.js"><link rel="prefetch" href="/assets/js/16.6987f89d.js"><link rel="prefetch" href="/assets/js/17.2807cff5.js"><link rel="prefetch" href="/assets/js/18.855e1707.js"><link rel="prefetch" href="/assets/js/19.6da24791.js"><link rel="prefetch" href="/assets/js/20.e24d4aef.js"><link rel="prefetch" href="/assets/js/21.6efc6fba.js"><link rel="prefetch" href="/assets/js/22.10447f0f.js"><link rel="prefetch" href="/assets/js/23.9154cc24.js"><link rel="prefetch" href="/assets/js/24.9ad529fc.js"><link rel="prefetch" href="/assets/js/25.4c092e0a.js"><link rel="prefetch" href="/assets/js/26.debdaa01.js"><link rel="prefetch" href="/assets/js/27.8b90b660.js"><link rel="prefetch" href="/assets/js/28.1a323e01.js"><link rel="prefetch" href="/assets/js/29.6f108fc9.js"><link rel="prefetch" href="/assets/js/3.7210d3aa.js"><link rel="prefetch" href="/assets/js/30.e7df1937.js"><link rel="prefetch" href="/assets/js/31.2cb3120f.js"><link rel="prefetch" href="/assets/js/33.cac3e2f0.js"><link rel="prefetch" href="/assets/js/34.19ea35c4.js"><link rel="prefetch" href="/assets/js/35.fadf5d03.js"><link rel="prefetch" href="/assets/js/36.88b681f1.js"><link rel="prefetch" href="/assets/js/37.2a799db9.js"><link rel="prefetch" href="/assets/js/38.2741a2bf.js"><link rel="prefetch" href="/assets/js/39.359ceb72.js"><link rel="prefetch" href="/assets/js/4.9e938666.js"><link rel="prefetch" href="/assets/js/40.56fd4a10.js"><link rel="prefetch" href="/assets/js/41.e72117ad.js"><link rel="prefetch" href="/assets/js/42.63a6e190.js"><link rel="prefetch" href="/assets/js/43.c8072421.js"><link rel="prefetch" href="/assets/js/44.84cd8367.js"><link rel="prefetch" href="/assets/js/45.0ac810b0.js"><link rel="prefetch" href="/assets/js/46.bb83ff34.js"><link rel="prefetch" href="/assets/js/47.a9333a81.js"><link rel="prefetch" href="/assets/js/48.526b5494.js"><link rel="prefetch" href="/assets/js/49.73b61cc6.js"><link rel="prefetch" href="/assets/js/5.88b252c7.js"><link rel="prefetch" href="/assets/js/50.f34ab799.js"><link rel="prefetch" href="/assets/js/51.d06a49d9.js"><link rel="prefetch" href="/assets/js/52.348d5482.js"><link rel="prefetch" href="/assets/js/6.0face56b.js"><link rel="prefetch" href="/assets/js/7.31eca58d.js"><link rel="prefetch" href="/assets/js/8.69e9ce95.js"><link rel="prefetch" href="/assets/js/9.f25df9e1.js">
    <link rel="stylesheet" href="/assets/css/0.styles.e1b3f17d.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">yanyan</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <!----></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><!---->  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><a href="/html/001" class="sidebar-heading clickable"><span>HTML</span> <span class="arrow right"></span></a> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><a href="/css/image" class="sidebar-heading clickable"><span>CSS</span> <span class="arrow right"></span></a> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><a href="/js/001" class="sidebar-heading clickable"><span>JS-基础</span> <span class="arrow right"></span></a> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><a href="/js-v8/001" class="sidebar-heading clickable"><span>JS-V8引擎原理 </span> <span class="arrow right"></span></a> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><a href="/js-async/001" class="sidebar-heading clickable"><span>JS-异步I/O及异步编程</span> <span class="arrow right"></span></a> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><a href="/http/000" class="sidebar-heading clickable open"><span>HTTP</span> <span class="arrow down"></span></a> <ul class="sidebar-links sidebar-group-items"><li><a href="/http/001.html" class="sidebar-link">01 HTTP 的特点？HTTP 的缺点</a></li><li><a href="/http/002.html" class="sidebar-link">02 说一说从输入URL到页面呈现发生了什么？——网络篇</a></li><li><a href="/http/003.html" class="sidebar-link">03 说一说从输入URL到页面呈现发生了什么？——解析算法篇</a></li><li><a href="/http/004.html" class="sidebar-link">04 说一说从输入URL到页面呈现发生了什么？——渲染过程篇</a></li><li><a href="/http/005.html" class="sidebar-link">05 谈谈你对重绘和回流的理解</a></li><li><a href="/http/006.html" class="sidebar-link">06 XSS攻击</a></li><li><a href="/http/007.html" class="sidebar-link">07 CSRF攻击</a></li><li><a href="/http/008.html" class="sidebar-link">08 (传统RSA版本)HTTPS为什么让数据传输更安全</a></li><li><a href="/http/009.html" class="sidebar-link">09 Https TLS 1.2  1.3</a></li><li><a href="/http/010.html" class="active sidebar-link">10 Cookie</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/http/011.html" class="sidebar-link">11 什么是跨域？浏览器如何拦截响应？如何解决</a></li><li><a href="/http/012.html" class="sidebar-link">12 Http2</a></li><li><a href="/http/013.html" class="sidebar-link">13 Http缓存</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><a href="/extend/002" class="sidebar-heading clickable"><span>拓展阅读</span> <span class="arrow right"></span></a> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="cookie"><a href="#cookie" class="header-anchor">#</a> Cookie</h1> <p>cookie在web开发中时常被用到，也是面试官喜欢问的一块技术，很多人或许和我以前一样，只知其一不知其二，谈起web存储，都会答localStorage、sessionStorage、还有就是cookie，然后一些区别啊什么的倒背如流，cookie的优缺点也了然于心，但是当你看完这块内容之后，你会对cookie有另外独到的见解，希望以后问到这块技术，或者项目中遇到这个你都会处理</p> <h3 id="cookie是什么"><a href="#cookie是什么" class="header-anchor">#</a> cookie是什么</h3> <p>这个讲起来很简单，了解http的同学，肯定知道，http是一个不保存状态的协议，什么叫不保存状态，就是一个服务器是不清楚是不是同一个浏览器在访问他，在cookie之前，有另外的技术是可以解决，这里简单讲一下，就是在请求中插入一个token，然后在发送请求的时候，把这个东西带给服务器，这种方式是易出错，所以有了cookie的出现</p> <p><a data-fancybox="" title="cookie" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookie.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookie.png" alt="cookie"></a></p> <p>cookie是什么，cookie就是一种浏览器管理状态的一个文件，它有name，也有value，后面那些看不见的是Domain、path等等，我们后面会介绍</p> <h3 id="cookie原理"><a href="#cookie原理" class="header-anchor">#</a> cookie原理</h3> <p><a data-fancybox="" title="cookieSend" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieSend.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieSend.png" alt="cookieSend"></a></p> <p>第一次访问网站的时候，浏览器发出请求，服务器响应请求后，会将cookie放入到响应请求中，在浏览器第二次发请求的时候，会把cookie带过去，服务端会辨别用户身份，当然服务器也可以修改cookie内容</p> <h3 id="cookie不可跨域"><a href="#cookie不可跨域" class="header-anchor">#</a> cookie不可跨域</h3> <p>我就几个例子你就懂了，当我打开百度的网页，我要设置一个cookie的时候，我的指令如下</p> <div class="language-js extra-class"><pre class="language-js"><code>javascript<span class="token operator">:</span>document<span class="token punctuation">.</span>cookie<span class="token operator">=</span><span class="token string">'myname=laihuamin;path=/;domain=.baidu.com'</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code>javascript<span class="token operator">:</span>document<span class="token punctuation">.</span>cookie<span class="token operator">=</span><span class="token string">'myname=huaminlai;path=/;domain=.google.com'</span><span class="token punctuation">;</span>
</code></pre></div><p>当我将这两个语句都放到浏览器控制台运行的时候，你会发现一点,注意，上面两个cookie的值是不相同的，看清楚
<a data-fancybox="" title="cookieDontDomain" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieDonDomain.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieDonDomain.png" alt="cookieDontDomain"></a>
显而易见的是，真正能把cookie设置上去的只有domain是.baidu.com的cookie绑定到了域名上，所以上面所说的不可跨域性，就是不能在不同的域名下用，每个cookie都会绑定单一的域名</p> <h3 id="cookie的属性"><a href="#cookie的属性" class="header-anchor">#</a> cookie的属性</h3> <p>cookie的属性众多，我们可以来看一下下面这张图，然后我们一个一个分析</p> <p><a data-fancybox="" title="cookieAttr" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieAttr.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieAttr.png" alt="cookieAttr"></a></p> <h4 id="name"><a href="#name" class="header-anchor">#</a> name</h4> <p>这个显而易见，就是代表cookie的名字的意思，一个域名下绑定的cookie，name不能相同，相同的name的值会被覆盖掉，有兴趣的同学可以试一试，我在项目中切实用到过</p> <h4 id="value"><a href="#value" class="header-anchor">#</a> value</h4> <p>这个就是每个cookie拥有的一个属性，它表示cookie的值，但是我在这里想说的不是这个，因为我在网上看到两种说法，如下：<br>
1.cookie的值必须被URL编码<br>
2.对cookie的值进行编码不是必须的，还举了原始文档中所说的，仅对三种符号必须进行编码：分号、逗号和空格</p> <p>这个东西得一分为二来看，先看下面的图</p> <p><a data-fancybox="" title="cookievalue" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieValue.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieValue.png" alt="cookievalue"></a></p> <p>我在网上看到那么一种说法：</p> <blockquote><p>由于cookie规定是名称/值是不允许包含分号，逗号，空格的，所以为了不给用户到来麻烦，考虑服务器的兼容性，任何存储cookie的数据都应该被编码。</p></blockquote> <h4 id="domain"><a href="#domain" class="header-anchor">#</a> domain</h4> <p>这个是指的域名，这个代表的是，cookie绑定的域名，如果没有设置，就会自动绑定到执行语句的当前域，还有值得注意的点，统一个域名下的二级域名也是不可以交换使用cookie的，比如，<a href="http://xn--www-x69dw01tlpp.baidu.xn--comimage-1c2n.baidu.com" target="_blank" rel="noopener noreferrer">你设置www.baidu.com和image.baidu.com<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>,依旧是不能公用的</p> <h4 id="path"><a href="#path" class="header-anchor">#</a> path</h4> <p>path这个属性默认是'/'，这个值匹配的是web的路由，举个例子：</p> <div class="language- extra-class"><pre class="language-text"><code>//默认路径
www.baidu.com
//blog路径
www.baidu.com/blog
</code></pre></div><p>我为什么说的是匹配呢，就是当你路径设置成/blog的时候，其实它会给/blog、/blogabc等等的绑定cookie</p> <h4 id="cookie的有效期"><a href="#cookie的有效期" class="header-anchor">#</a> cookie的有效期</h4> <p><a data-fancybox="" title="cookieMaxAge" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieMaxAge.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieMaxAge.png" alt="cookieMaxAge"></a></p> <p>什么是有效期，就是图中的Expires属性，一般浏览器的cookie都是默认储存的，当关闭浏览器结束这个会话的时候，这个cookie也就会被删除，这就是上图中的——session(会话储存)。</p> <p>如果你想要cookie存在一段时间，那么你可以通过设置Expires属性为未来的一个时间节点，Expires这个是代表当前时间的，这个属性已经逐渐被我们下面这个主人公所取代——Max-Age</p> <p>Max-Age，是以秒为单位的，Max-Age为正数时，cookie会在Max-Age秒之后，被删除，当Max-Age为负数时，表示的是临时储存，不会生出cookie文件，只会存在浏览器内存中，且只会在打开的浏览器窗口或者子窗口有效，一旦浏览器关闭，cookie就会消失，当Max-Age为0时，又会发生什么呢，删除cookie，因为cookie机制本身没有设置删除cookie，失效的cookie会被浏览器自动从内存中删除，所以，它实现的就是让cookie失效。</p> <h4 id="secure"><a href="#secure" class="header-anchor">#</a> secure</h4> <p><a data-fancybox="" title="cookieSecure" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieSecure.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieSecure.png" alt="cookieSecure"></a></p> <p>这个属性译为安全，http不仅是无状态的，还是不安全的协议，容易被劫持，打个比方，你在手机端浏览网页的时候，有没有中国移动图标跳出来过，闲言少叙，当这个属性设置为true时，此cookie只会在https和ssl等安全协议下传输</p> <ul><li>提示：这个属性并不能对客户端的cookie进行加密，不能保证绝对的安全性</li></ul> <h4 id="httponly"><a href="#httponly" class="header-anchor">#</a> HttpOnly</h4> <p>这个属性是面试的时候常考的，如果这个属性设置为true，就不能通过js脚本来获取cookie的值，能有效的防止xss攻击,看MDN的官方文档：
<a data-fancybox="" title="httpOnly" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieHttpOnly.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/cookieHttpOnly.png" alt="httpOnly"></a></p> <h4 id="samesite"><a href="#samesite" class="header-anchor">#</a> SameSite</h4> <p>a. 在Strict模式下，浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie，在其他网站请求都不能。</p> <p>b. 在Lax模式，就宽松一点了，但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie，其他情况均不能。 (chrome 80后Lax为默认)</p> <p>c. 在None模式下，也就是默认模式，请求会自动携带上 Cookie。 (chrome 80前为默认)</p> <h4 id="关于js操作cookie"><a href="#关于js操作cookie" class="header-anchor">#</a> 关于js操作cookie</h4> <p>document.cookie可以对cookie进行读写，看一下两条指令：</p> <div class="language- extra-class"><pre class="language-text"><code>//读取浏览器中的cookie
console.log(document.cookie);
//写入cookie
document.cookie='myname=laihuamin;path=/;domain=.baidu.com';
</code></pre></div><h4 id="服务端如何去设置cookie"><a href="#服务端如何去设置cookie" class="header-anchor">#</a> 服务端如何去设置cookie</h4> <p>关于怎么设置cookie，我们只要打开控制台，看一个http的请求头和响应头中的东西即可明白：
<a data-fancybox="" title="setCookie" href="http://laihuamin.oss-cn-beijing.aliyuncs.com/setCookie.png"><img src="http://laihuamin.oss-cn-beijing.aliyuncs.com/setCookie.png" alt="setCookie"></a></p> <p>服务端就是通过setCookie来设置cookie的，注意点，要设置多个cookie时，得多写几个setCookie，我们还可以从上图看到，请求可以携带cookie给后端。</p> <h4 id="cookie-的缺点"><a href="#cookie-的缺点" class="header-anchor">#</a> Cookie 的缺点</h4> <ol><li><p>容量缺陷。Cookie 的体积上限只有4KB，只能用来存储少量的信息。</p></li> <li><p>性能缺陷。Cookie 紧跟域名，不管域名下面的某一个地址需不需要这个 Cookie ，请求都会携带上完整的 Cookie，这样随着请求数的增多，其实会造成巨大的性能浪费的，因为请求携带了很多不必要的内容。但可以通过Domain和Path指定作用域来解决。</p></li> <li><p>安全缺陷。由于 Cookie 以纯文本的形式在浏览器和服务器中传递，很容易被非法用户截获，然后进行一系列的篡改，在 Cookie 的有效期内重新发送给服务器，这是相当危险的。另外，在HttpOnly为 false 的情况下，Cookie 信息能直接通过 JS 脚本来读取。</p></li></ol> <p>作者：神三元
链接：<a href="https://juejin.im/post/5e76bd516fb9a07cce750746" target="_blank" rel="noopener noreferrer">https://juejin.im/post/5e76bd516fb9a07cce750746<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>
来源：掘金
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</p> <h4 id="参考资料"><a href="#参考资料" class="header-anchor">#</a> 参考资料</h4> <p><a href="https://juejin.im/post/5b18d322e51d4506cf10af7c" target="_blank" rel="noopener noreferrer">聊一聊 cookie<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a><br> <a href="https://juejin.im/post/5e76bd516fb9a07cce750746#heading-44" target="_blank" rel="noopener noreferrer">HTTP灵魂之问，巩固你的 HTTP 知识体系<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/http/009.html" class="prev">
        09 Https TLS 1.2  1.3
      </a></span> <span class="next"><a href="/http/011.html">
        11 什么是跨域？浏览器如何拦截响应？如何解决
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.e358a08d.js" defer></script><script src="/assets/js/2.88fa18d1.js" defer></script><script src="/assets/js/32.eb64932c.js" defer></script>
  </body>
</html>
